%%%-------------------------------------------------------------------
%%% @author chenlong
%%% @copyright (C) 2019, <COMPANY>
%%% @doc
%%% 客户端发来的消息处理函数，都被catch的了，可以直接写，统一throw(ok)被忽略
%%% @end
%%% Created : 15. 三月 2019 17:19
%%%-------------------------------------------------------------------
-module(role_role).
-author("chenlong").

-include("common.hrl").

%% API
-export([cs_role_login/1, cs_role_heart_beat/1]).

-export([doPlayerLogin_1/4]).


%%=============================EXPORTED FUNCTION====================================
%%sample_client登录
cs_role_login(#cs_role_login{code = AccountID, roleName = RoleName0, roleHead = RoleHead, roomID=RoomID}) when is_integer(AccountID) ->
	doPlayerLogin(integer_to_list(AccountID), util:term_to_list(RoleName0), util:term_to_list(RoleHead),RoomID);
%%登录验证
cs_role_login(#cs_role_login{code = Code, roleName = RoleName0, roleHead = RoleHead0, roomID=RoomID}) ->
	RoleName = util:term_to_list(RoleName0),
	RoleHead = util:term_to_list(RoleHead0),
	Url = "https://api.weixin.qq.com/sns/jscode2session?appid=wx023706cc1f7512ff&secret=c291c127c35456bfc0385564c262683d&js_code=" ++ binary_to_list(Code) ++ "&grant_type=authorization_code",
	Response = httpc:request(Url),
	case Response of
		{ok, Res} ->
			%%解析出openid
			Str = element(3, Res),
			TempStr = lists:last(string:split(Str, ":", trailing)),
			OpenID = string:substr(TempStr, 2, string:length(TempStr) - 3),
			doPlayerLogin(OpenID, RoleName, RoleHead,RoomID);
		{error, Reason} ->
			?ERR("cs_role_login error, Reason=~p", [Reason])
	end.

cs_role_heart_beat(#cs_role_heart_beat{}) ->
	?sendself(#sc_role_heart_beat{serverTime=util:now()}).


%%=============================LOCAL FUNCTION====================================
%%加载玩家数据之后
%%检测 是否在房间，在房间则推送到房间去，没有则推送房间列表
onPlayerLoad(RoleID,InitRoomID) ->
	%%处理离线事件
	role_offline:onOfflineEvent(),
	case checkRoleInRoom(RoleID) of
		0 ->%%没在房间中
			%%是否想直接进入某个房间
			case room_manager:getEtsRoom(InitRoomID) of
				#ets_room{}=EtsRoom ->
					role_room:onResEnterRoom(EtsRoom),
					ok;
				_ -> ok
			end;
		RoomID ->%%在房间中
			EtsRoom = room_manager:getEtsRoom(RoomID),
			role_room:onResEnterRoom(EtsRoom),
			ok
	end,
	ok.

%%遍历检测，是否在某个房间
%%return RoomID
checkRoleInRoom(RoleID) ->
	CheckFun = fun(RoomID) ->
		#ets_room{playerList = PlayerList} = room_manager:getEtsRoom(RoomID),
		lists:keymember(RoleID, #room_player.playerID, PlayerList)
	           end,
	util:ets_foreach_return(?ETS_ROOM, CheckFun, ?TRUE, 0).

doPlayerLogin(OpenID, RoleName, RoleHead,InitRoomID) ->
	%%查找是否有玩家数据
	RoleID = case db_sql:getAccountRoleID(OpenID) of
		         0 ->
			         %%没有数据，创建数据
			         RoleID0 = tk_id:gen_roleID(),
			         db_sql:setAccountRoleID(OpenID, RoleID0),
			         RoleID0;
		         RoleID0 ->
			         RoleID0
	         end,
	%%检测是否有RoleID已经在线上，防止重复登录，先让对方RoleID下线
	case ets:member(?ETS_ROLE_ONLINE, RoleID) of
		?TRUE ->
			#role_online{rolePID = RolePID} = role_lib:getRoleOnline(RoleID),
			gen_server:cast(RolePID, {login_again, self(), {RoleID, RoleName, RoleHead,InitRoomID}});
		_ ->
			doPlayerLogin_1(RoleID, RoleName, RoleHead,InitRoomID)
	end,
	ok.
doPlayerLogin_1(RoleID, RoleName, RoleHead,InitRoomID) ->
	Role = case db_sql:getRole(RoleID) of
		       #role{} = R -> R;
		       _ ->
			       InitRole = #role{
				       roleID = RoleID,
				       roleName = RoleName,
				       headurl = RoleHead
			       },
			       db_sql:setRole(InitRole),
			       InitRole
	       end,
	role_data:setRole(Role),
	?CATCH(erlang:register(util:roleRegName(RoleID), self())),
	ets:insert(?ETS_ROLE_ONLINE, #role_online{roleID = RoleID, sendToSocketFun = get(?SEND_TO_SOCKET_FUN), socket = get(?ROLE_SOCKET), rolePID = self()}),
	?sendself(#sc_role_login{result = 0, roleID = RoleID}),
	%%每次更新一下，最新昵称和头像
	NewRole = Role#role{roleName = RoleName, headurl = RoleHead},
	db_sql:setRole(NewRole),
	%%新加入public没必要，但是更新却有必要，所以这里加上了update
	role_public_server ! {updatePublic, NewRole},
	onPlayerLoad(RoleID,InitRoomID),
	ok.